package be.darling.scrt.statistics;

import be.darling.scrt.data.Condition;
import be.darling.scrt.data.Randomization;
import be.darling.scrt.utilities.Plugin;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.w3c.dom.Node;

/**
 * Created by IntelliJ IDEA.
 * User: geert
 * Date: Nov 21, 2007
 * Time: 2:13:40 PM
 * To change this template use File | Settings | File Templates.
 */
public abstract class Statistic implements Plugin {

    private HashMap<String, Object> options = new HashMap<String, Object>();
    private Node nodeOptions;

    private Map<String, Condition> conditions = new HashMap<String, Condition>();

    private String name, type, description;

    int dimension = 0; // multivariate data
    double observedValue;
    double lastValue;

    double total = 0;
    double higher = 0;

    long nanoTime;

    public abstract double calc(Randomization randomization); // return Comparable object?

    public void reset(){
        lastValue = 0;
        total = 0;
        higher = 0;
    }

    public int getDimension() {
        return dimension;
    }

    public void setDimension(int dimension) {
        this.dimension = dimension;
    }

    public long getNanoTime() {
        return nanoTime;
    }

    public void setNanoTime(long nanoTime) {
        this.nanoTime = nanoTime;
    }

    public void addTime(long nanoTime) {
        this.nanoTime += nanoTime;
    }
    

    public double getObservedValue() {
        return observedValue;
    }

    public void setObservedValue(double observedValue) {
        this.observedValue = observedValue;
    }

    public double getLastValue() {
        return lastValue;
    }

    public void setLastValue(double lastValue) {
        total++;
        if (lastValue + Double.MIN_NORMAL  >= observedValue) higher ++;
        this.lastValue = lastValue;

    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Map<String, Condition> getConditions()
    {
        return this.conditions;
    }

    protected void addCondition(Condition condition)
    {
        conditions.put(condition.getName(), condition);
    }
    
    public double p(boolean exhaustive){
        if (exhaustive){
            return higher / total;
        } else {
            return higher / (total+1);            
        }
    }

    public Object getOption(String key)
    {
        return this.options.get(key);
    }

    public void setOptions(HashMap<String, Object> options) {
        if(options!=null)
            this.options.putAll(options);
    }

    public Node getNodeOptions() {
        return this.nodeOptions;
    }

    public void setOptions(Node options) {
        this.nodeOptions = options;
    }

    public abstract void init();

}
